////////////////////////////////////////////////
// DESCRIPTION:
//    Image Button
//
// Legal Notices:
//   Copyright (c) 2008, Telliam Consulting, LLC.
//   All rights reserved.
//
//   Redistribution and use in source and binary forms, with or without modification,
//   are permitted provided that the following conditions are met:
//
//   * Redistributions of source code must retain the above copyright notice, this list
//     of conditions and the following disclaimer.
//   * Redistributions in binary form must reproduce the above copyright notice, this
//     list of conditions and the following disclaimer in the documentation and/or other
//     materials provided with the distribution.
//   * Neither the name of Telliam Consulting nor the names of its contributors may be
//     used to endorse or promote products derived from this software without specific
//     prior written permission.
//
//   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
//   EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
//   OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
//   SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
//   INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
//   TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 
//   BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
//   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 
//   ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
//   DAMAGE. 
//

using System;
using System.Drawing;
using System.Runtime.CompilerServices;
using System.Windows.Forms;
using System.ComponentModel;
using System.Windows.Forms.VisualStyles;

namespace FusionWare.SPOT.EmulatorComponents
{
    /// <summary>Special control to provide an image as a button</summary>
    /// <remarks>This class supports rendering images for all button states</remarks>
    public class ImageButton : Control
    {
    // TODO: Support focus to allow visual cues for those not using a mouse
    //       Use a statemachine to manage the state transitions as needed.
        
        /// <summary>Default Constructor</summary>
        public ImageButton()
        {
        }

        /// <summary>Checks to see if the key press is the shortcut key for the button</summary>
        /// <param name="keyData">kKeyData about the key press</param>
        /// <returns>true if this button handles the key</returns>
        protected override bool IsInputKey(Keys keyData)
        {
            return (this._InputKey == keyData);
        }

        /// <summary>Handles invalidating the control when the button state changes</summary>
        /// <param name="NewState">Indicates if the new button state</param>
        protected virtual void OnButtonStateChanged(bool NewState)
        {
            if (this.Pressed != NewState)
            {
                this.Pressed = NewState;
                this.Invalidate();
            }
        }

        /// <summary>Handles key presses for the control</summary>
        /// <param name="e">key event info</param>
        protected override void OnKeyDown(KeyEventArgs e)
        {
            this.OnButtonStateChanged(true);
            base.OnKeyDown(e);
        }

        /// <summary>Handles key presses for the control</summary>
        /// <param name="e">key event info</param>
        protected override void OnKeyUp(KeyEventArgs e)
        {
            this.OnButtonStateChanged(false);
            base.OnKeyUp(e);
        }

        /// <summary>Handles mouse buttons for the control</summary>
        /// <param name="e">key event info</param>
        protected override void OnMouseDown(MouseEventArgs e)
        {
            this.OnButtonStateChanged(true);
            base.OnMouseDown(e);
        }

        /// <summary>Handles mouse buttons for the control</summary>
        /// <param name="e">key event info</param>
        protected override void OnMouseUp(MouseEventArgs e)
        {
            this.OnButtonStateChanged(false);
            base.OnMouseUp(e);
        }
        /// <summary>Handles painting the control</summary>
        /// <param name="e">Event paramaters</param>
        /// <remarks>
        /// If no image is set for the current button state this uses 
        /// <see cref="ButtonRenderer">ButtonRender</see> to draw the 
        /// button in it's current state. 
        /// </remarks>
        protected override void OnPaint(PaintEventArgs e)
        {
            Image img = this.Images[this.Pressed ? 1 : 0];
            if(img != null)
                e.Graphics.DrawImage(img, 0, 0, this.Width, this.Height);
            else
            {
                PushButtonState state = this.Pressed ? PushButtonState.Pressed : PushButtonState.Normal;
                ButtonRenderer.DrawButton(e.Graphics, e.ClipRectangle, state);
            }
        }

        /// <summary>Buttons Image in the "Up" state</summary>
        [ 
            CategoryAttribute("Appearance"), 
            DescriptionAttribute("Sets the Image for the button in the 'Up' State"), 
            DefaultValue(null)
        ] 
        public Image ButtonUpImage
        {
            get { return this.Images[0]; }
            set { this.Images[0] = value; }
        }

        /// <summary>Buttons Image in the "Down" State</summary>
        [
            CategoryAttribute("Appearance"),
            DescriptionAttribute("Sets the Image for the button in the 'Down' State"),
            DefaultValue(null)
        ]
        public Image ButtonDownImage
        {
            get { return this.Images[1]; }
            set { this.Images[1] = value; }
        }

        /// <summary>Shortcut key for this button</summary>
        [
            CategoryAttribute("Behavior"),
            DescriptionAttribute("Identifies the shortcut key for this button"),
            DefaultValue(Keys.Space)
        ]
        public Keys InputKey
        {
            get { return this._InputKey; }
            set { this._InputKey = value; }
        }
        private Keys _InputKey = Keys.Space;

        private bool Pressed = false;
        private Image[] Images = new Image[2];
    }
}

